package net.obxlabs.tweetpad.stats;

import java.util.*;
import net.nexttext.*;
import net.silentlycrashing.util.*;
import processing.core.*;

public class Counter {
	public static final int TEXT_OFFSET_Y = 13;
	public static final int LINE_OFFSET_Y = 40;
	public static final int CHAR_UNIT = -10;
	public static final int SRC_UNIT = -2;
	public static final int MAX_COUNT = 400;
	public static final int CHARS_PER_SLICE = 4;
	
	public static final int NUM_SOURCES = 4;
	public static final int WEB = 0;
	public static final int TXT = 1;
	public static final int IM = 2;
	public static final int API = 3;
	
	public static final int[] SRC_TXT_OFFSET = { 33, 37, 37, 36 };
	public static final int[] CHAR_TXT_OFFSET = { 4, -54, -120 };
	public static final int[][] LINE_COLORS = { 
		{ 153, 153, 51 },
		{ 255, 153, 102 },
		{ 102, 153, 153 },
		{ 204, 51, 0 }
	};
	
	private PApplet p;
	private CharLine[] charLines;
	private SourceLine[] sourceLines;
	private List<int[]> countList;
	
	public Counter(PApplet p, Book book) {
		this.p = p;
		countList = Collections.synchronizedList(new LinkedList<int[]>());
		charLines = new CharLine[NUM_SOURCES];
		sourceLines = new SourceLine[NUM_SOURCES];
		int srcStartX = p.width-SourceLine.LENGTH*NUM_SOURCES;
		for (int i=0; i < NUM_SOURCES; i++) {
			charLines[i] = new CharLine(p, p.height-LINE_OFFSET_Y, CHAR_UNIT, p.color(LINE_COLORS[i][0], LINE_COLORS[i][1], LINE_COLORS[i][2]), MiscMath.randRange(1, 4));
			sourceLines[i] = new SourceLine(p, p.height-LINE_OFFSET_Y, SRC_UNIT, srcStartX, i, p.color(LINE_COLORS[i][0], LINE_COLORS[i][1], LINE_COLORS[i][2]));
		}
		
		// draw the counter text
		p.noStroke();
        p.fill(51, 102, 153);
        int endCharX = p.width-CharLine.OFFSET_X;
        book.addText("1", 0+CHAR_TXT_OFFSET[0], p.height-TEXT_OFFSET_Y);
        book.addText("tweetPad", endCharX/2+CHAR_TXT_OFFSET[1], p.height-TEXT_OFFSET_Y);
        book.addText("140", endCharX+CHAR_TXT_OFFSET[2], p.height-TEXT_OFFSET_Y);
        p.fill(102, 102, 51);
        // TODO should be automated with a for-loop at some point
        book.addText("web", srcStartX+SourceLine.LENGTH*0+SRC_TXT_OFFSET[0], p.height-TEXT_OFFSET_Y);
        book.addText("sms", srcStartX+SourceLine.LENGTH*1+SRC_TXT_OFFSET[1], p.height-TEXT_OFFSET_Y);
        book.addText("im", srcStartX+SourceLine.LENGTH*2+SRC_TXT_OFFSET[2], p.height-TEXT_OFFSET_Y);
        book.addText("api", srcStartX+SourceLine.LENGTH*3+SRC_TXT_OFFSET[3], p.height-TEXT_OFFSET_Y);
	}
	
	public void draw() {
		for (int i=0; i < NUM_SOURCES; i++) {
			sourceLines[i].draw();
			charLines[i].draw();
		}
		
		p.strokeWeight(1);
	}
	
	public void addCount(String source, String msg) {
		int[] unit = new int[2];  // { source, msg }
		unit[0] = sourceStrToInt(source);
		unit[1] = (int)Math.floor((msg.length()-1)/CHARS_PER_SLICE);
		
		// add the new count
		countList.add(unit);
		
		if (countList.size() > MAX_COUNT) {
			// remove the first item
			int[] firstUnit = countList.remove(0);
			
			if (firstUnit[0] != unit[0]) {
				sourceLines[unit[0]].addSourceCount();
				sourceLines[firstUnit[0]].subSourceCount();
			}
			// else: sources are the same, we don't need to do anything
			
			if (firstUnit[1] != unit[1]) {
				charLines[unit[0]].addCharCount(unit[1]);
				charLines[firstUnit[0]].subCharCount(firstUnit[1]);
			}
			// else: char counts are the same, we don't need to do anything
			
		} else {
			sourceLines[unit[0]].addSourceCount();
			charLines[unit[0]].addCharCount(unit[1]);
		}
	}
	
	public static int sourceStrToInt(String str) {
		if (str.compareTo("web") == 0) {
			//System.out.println("Adding 'web'");
			return WEB;
		} else if (str.compareTo("<a href=\"http://twitter.com/help/mobile\">txt</a>") == 0) {
			//System.out.println("Adding 'txt'");
			return TXT;
		} else if (str.compareTo("im") == 0) {
			//System.out.println("Adding 'im'");
			return IM;
		} else {
			//System.out.println("Adding 'api'");
			return API;
		}
	}

	public void reset() {
		for (int i=0; i < NUM_SOURCES; i++) {
			sourceLines[i].reset();
			charLines[i].reset();
		}
		countList.clear();
	}
}
